package cn.edu.xust.communication;

import cn.edu.xust.communication.server.CommonOp;
import cn.edu.xust.configuration.exception.Default200Exception;
import cn.edu.xust.entity.AmmeterParameterEntity;
import cn.edu.xust.communication.enums.AmmeterReader;
import cn.edu.xust.communication.enums.AmmeterStatusEnum;
import cn.edu.xust.communication.model.Result;
import cn.edu.xust.communication.protocol.Dlt645Frame;
import cn.edu.xust.communication.server.handler.NettyServerDefaultHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.Objects;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 支持DLT645-2007协议数据解析的具体实现
 *
 * @author ：huangxin
 * @modified ：
 * @since ：2020/03/19 11:21
 */

@Slf4j
public class AmmeterAutoReader extends AbstractAmmeterReaderWriterAdapter {

    /**
     * 电表端的IP
     */
    private String ammeterChannelIp;
    /**
     * 电表编号
     */
    private String ammeterId;


    public AmmeterAutoReader(String ammeterChannelIp, String ammeterId) {
        this.ammeterChannelIp = ammeterChannelIp;
        this.ammeterId = ammeterId;
    }


    //读取当前电流的电压值
    @Override
    public Double readCurrentVA() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(),
                "33 34 34 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentAVoltage();
        }
        return null;
    }

    @Override
    public Double readCurrentVB() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 35 34 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentBVoltage();
        }
        return null;
    }

    @Override
    public Double readCurrentVC() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 36 34 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentCVoltage();
        }
        return null;
    }

    @Override
    public Double readCurrentIA() throws Default200Exception {

        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 34 35 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            log.info("查电流:{}", ammeterParameter.getCurrentACurrent());
            return ammeterParameter.getCurrentACurrent();
        }
        return null;
    }

    @Override
    public Double readCurrentIB() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 35 35 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentBCurrent();
        }
        return null;
    }

    @Override
    public Double readCurrentIC() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 36 35 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentCCurrent();
        }
        return null;
    }

    @Override
    public Double readCurrentActivePower() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 33 36 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentActivePower();
        }
        return null;
    }

    @Override
    public Double readCurrentReactivePower() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 33 37 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentReactivePower();
        }
        return null;
    }


    //读电流功率因数
    @Override
    public Double readCurrentPowerFactor() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 33 39 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentPowerFactor();
        }
        return null;
    }


    //读电流总视在功率
    @Override
    public Double readCurrentTotalApparentPower() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 33 38 35");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentTotalActivePower();
        }
        return null;
    }


    //当前总有效能量
    @Override
    public Double readCurrentTotalActiveEnergy() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 33 33 33");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentTotalActivePower();
        }
        return null;
    }


    //读电流正有效能量
    @Override
    public Double readCurrentPositiveActiveEnergy() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 33 34 33");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentPositiveActivePower();
        }
        return null;
    }


    //读电流负有效能量
    @Override
    public Double readCurrentNegativeActiveEnergy() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "33 33 35 33");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getCurrentNegtiveActivePower();
        }
        return null;
    }

    //读电表状态
    @Override
    public String readState() throws Default200Exception {
        Result result = this.sendCommand(AmmeterReader.MasterRequestFrame.getControlCode(),
                AmmeterReader.MasterRequestFrame.getBaseDataLen(), "36 38 33 37");
        if (Objects.nonNull(result)) {
            AmmeterParameterEntity ammeterParameter = this.parseAndPersistenceData(result);
            return ammeterParameter.getState();
        }
        return null;
    }

    /**
     * 解析并持久化数据，之后再将数据返回给调用者
     */
    private AmmeterParameterEntity parseAndPersistenceData(Result result) {
        Dlt645Frame frame = new Dlt645Frame();
        AmmeterParameterEntity ammeterParameter = frame.analysis(result.getMessage().length() > 8 ? result.getMessage().substring(8) : "");
        return ammeterParameter;
    }

    /**
     * 发送指令
     *
     * @param controlCode        控制码
     * @param dataLen            数据长度
     * @param dataIdentification 数据标识
     */
    private Result sendCommand(String controlCode, String dataLen, String dataIdentification) throws Default200Exception {
        if (StringUtils.isEmpty(controlCode) || StringUtils.isEmpty(dataLen) || StringUtils.isEmpty(dataIdentification)
                || StringUtils.isEmpty(this.ammeterId) || StringUtils.isEmpty(this.ammeterChannelIp)) {
            throw new IllegalArgumentException("消息参数不能是空");
        }
        Dlt645Frame frame = new Dlt645Frame(this.ammeterId, controlCode, dataLen, dataIdentification);
        log.info("单独读电表状态，生成的指令是:{}", frame.createFrame());
        return CommonOp.writeCommand(this.ammeterChannelIp, frame.createFrame(), UUID.randomUUID().toString());
    }


}
